﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "QFamilyTreeWidget.h"
#include "IUIConfiguration.h"
#include "IUiDocumentViewManager.h"
#include "IUiView.h"
#include "IJournalCommandData.h"

#include <QMouseEvent>
#include <QApplication>
#include <QMenu>

#include "IGcmpUserDrag.h"
#include "TestDragEventData.h"
#include "GcmpCommandNames.h"
#include "CommandParameters.h"
#include "JournalUtils.h"
#include "IGcmpUserDragFactory.h"
#include "IUserDragEvent.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

QFamilyTreeWidget::QFamilyTreeWidget(QWidget *parent /*= NULL*/)
    : QTreeWidget(parent)
    , m_bShowFamilyManagementMenuItem(true)
    ,m_opDropEventHandler(nullptr)
{
    this->setSelectionMode(QAbstractItemView::ExtendedSelection);

    this->setDragEnabled(true);
    this->setStyleSheet("QFamilyTreeWidget::item:selected{ background-color: rgb(51, 153, 255)} QFamilyTreeWidget{ font-family: \"Microsoft YaHei\";}");

    m_treeMenu = NEW_AS_QT_CHILD(QMenu, this);
    m_treeMenu->setObjectName("treeMenu");
    setFocusPolicy(Qt::ClickFocus);
    connect(this, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnFamilyTreeItemDoubleClicked(QTreeWidgetItem*, int)));

    //初始化自响应的默认族命令
    IUIConfiguration *pUIconfig = IMPLEMENTATION(IUIConfiguration);
    if (pUIconfig)
    {
        m_bShowFamilyManagementMenuItem = pUIconfig->ShowFamilyManagementMenuItem();
        m_CreateFamilyInstanceCmdId = pUIconfig->GetCreateFamilyInstanceCommandId();
        m_RenameFamilyCmdId = pUIconfig->GetRenameFamilyCommandId();
        m_EditFamilyCmdId = pUIconfig->GetEditFamilyCommandId();
        m_SaveFamilyAsCmdId = pUIconfig->GetSaveAsFamilyCommandId();
        m_LoadFamilyCmdId = pUIconfig->GetLoadFamilyCommandId();
        m_RemoveSelectedFamliesCmdId = pUIconfig->GetDeleteFamilyCommandId();
    }

}

QFamilyTreeWidget::~QFamilyTreeWidget()
{
}



void QFamilyTreeWidget::UpdateView(IDocument* pDoc)
{
    QTreeWidgetItem *pRootItem = topLevelItem(0);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pRootItem, L"族的树结构错误",L"GDMPLab",L"2024-03-30");
    QFamilyTreeWidgetUtil::UpdateFamilyItems(pRootItem, pDoc, m_icons);
}

void QFamilyTreeWidget::CreateFamilyInstance()
{
    QFamilyTreeWidgetUtil::CreateFamilyInstance(currentItem(), m_CreateFamilyInstanceCmdId);
}

void QFamilyTreeWidget::RenameFamily()
{
    QFamilyTreeWidgetUtil::RenameFamily(currentItem(),m_RenameFamilyCmdId);
}

void QFamilyTreeWidget::EditFamily()
{
    QFamilyTreeWidgetUtil::EditFamily(currentItem(), m_EditFamilyCmdId);
}

void QFamilyTreeWidget::LoadFamily()
{
    QFamilyTreeWidgetUtil::LoadFamily(currentItem(), m_LoadFamilyCmdId);
}

void QFamilyTreeWidget::RemoveFamily()
{
    QFamilyTreeWidgetUtil::RemoveSelectedFamlies(selectedItems(), m_RemoveSelectedFamliesCmdId);
}

void QFamilyTreeWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        m_startDragPoint = event->pos();
    }
    else if (event->button() == Qt::RightButton)
    {
        QTreeWidgetItem *item = this->itemAt(event->pos());
        if (item != nullptr)
        {
            if (!item->isSelected())
            {
                this->clearSelection();
                this->setCurrentItem(item);
                item->setSelected(true);
            }
            if (m_treeMenu != nullptr)
            {
                QList<QTreeWidgetItem*> selectedItem = selectedItems();
                UpdateFamilyTreeItemContextMenu(selectedItem);
                if (!m_treeMenu->isEmpty())
                {
                    m_treeMenu->exec(QCursor::pos()); //在当前鼠标位置显示
                }
            }
        }
    }

    QTreeWidget::mousePressEvent(event);
}

void QFamilyTreeWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        int dragDistance = (event->pos() - m_startDragPoint).manhattanLength();
        if (dragDistance > QApplication::startDragDistance())
        {
            performDrag();
        }
    }
}

void QFamilyTreeWidget::performDrag()
{
    QTreeWidgetItem *item = currentItem();
    if (item)
    {
        QVariant data = item->data(0,FAMILY_USER_DATA_ROLE);
        QTreeWidgetItem* pParent = item->parent();
        if(data.toInt() != TWNT_FAMILYTYPE || !pParent)
            return;

        if (!JournalUtils::IsInReplay())
        {
            // 添加拖放事件处理者
            IUiDocumentViewManager* pUiDocViewMgr = IUiDocumentViewManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocViewMgr, L"pUiDocViewMgr为空",L"GDMPLab",L"2024-03-30");
            IUiView* pCurrentView = pUiDocViewMgr->GetCurrentUiView();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pCurrentView, L"pCurrentView为空",L"GDMPLab",L"2024-03-30");

            m_opDropEventHandler = NEW_AS_OWNER_PTR(TestDropEventHandler);
            DBG_WARN_AND_RETURN_VOID_UNLESS(IGcmpUserDragFactory::Get(), L"IGcmpUserDragFactory::Get()返回为空!",L"GDMPLab",L"2024-03-30");
            IUserDragEvent* pDropEvent = IGcmpUserDragFactory::Get()->GetEvent();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pDropEvent, L"pEvent为空",L"GDMPLab",L"2024-03-30");
            pDropEvent->Add(m_opDropEventHandler.get());

            QString iconPath = QFamilyTreeWidgetUtil::GetIconPathForFamilyRootItem();

            //日志记录
            OwnerPtr<IJournalCommandData> opJournalCommandData = IJournalCommandData::Create();
            DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCommandData, L"opJournalCommandData为空",L"GDMPLab",L"2024-03-30");
            opJournalCommandData->SetCommandName(ID_CMD_TEST_DRAG_DROP);

            CommandParameters paramArray;
            paramArray[L"FamilyName"] = pParent->text(0).toStdWString();
            paramArray[L"FamilyType"] = item->text(0).toStdWString();
            paramArray[L"WinId"] = winId();
            paramArray[L"IconPath"] = iconPath.toStdWString();
            paramArray[L"DragOrDrop"] = 0; //0表示拖动  1表示放下
            opJournalCommandData->SetParameterArray(paramArray);
            JournalUtils::RecordCommand(TransferOwnership(opJournalCommandData));
            ////////

            OwnerPtr<TestDragEventData> opUserData = NEW_AS_OWNER_PTR(TestDragEventData);
            opUserData->SetFamilyName(pParent->text(0).toStdWString());
            opUserData->SetFamilyType(item->text(0).toStdWString());
            DBG_WARN_AND_RETURN_VOID_UNLESS(IGcmpUserDragFactory::Get(), L"IGcmpUserDragFactory::Get()返回空指针",L"GDMPLab",L"2024-03-30");
            IGcmpUserDrag *pDrag = IGcmpUserDragFactory::Get()->CreateUserDrag(effectiveWinId());
            DBG_WARN_AND_RETURN_VOID_UNLESS(pDrag, L"IGcmpUserDrag::Create() 返回空指针",L"GDMPLab",L"2024-03-30");
            pDrag->SetDragEventData(TransferOwnership(opUserData));
            pDrag->SetDragPixmap(iconPath.toStdWString());
            pDrag->Execute();

            pDropEvent->Delete(m_opDropEventHandler.get());

        }   
        
    }
}

void QFamilyTreeWidget::UpdateFamilyTreeItemContextMenu(const QList<QTreeWidgetItem*>& selectedItem)
{
    m_treeMenu->clear();

    if (selectedItem.size() == 1)
    {
        // 单选
        int nodeType = selectedItem[0]->data(0, FAMILY_USER_DATA_ROLE).toInt();
        if (nodeType == TWNT_FAMILY)
        {
            if (m_bShowFamilyManagementMenuItem)
            {
                QAction* pRenameFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"重命名(&R)")));
                connect(pRenameFamilyAction, SIGNAL(triggered(bool)), this, SLOT(RenameFamily()));

                if (!m_EditFamilyCmdId.empty())
                {
                    QAction* pEditFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"编辑(&E)")));
                    connect(pEditFamilyAction, SIGNAL(triggered(bool)), this, SLOT(EditFamily()));
                }

                QAction* pRemoveFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除(&D)")));
                connect(pRemoveFamilyAction, SIGNAL(triggered(bool)), this, SLOT(RemoveFamily()));
            }
        }
        else if (nodeType == TWNT_FAMILYTYPE)
        {
            QAction* pCreateFamilyInstance = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"创建实例")));
            connect(pCreateFamilyInstance, SIGNAL(triggered(bool)), this, SLOT(CreateFamilyInstance()));
        }
        else if (nodeType == TWNT_FAMILY_ROOT)
        {
            if (m_bShowFamilyManagementMenuItem)
            {
                QAction* pLoadFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"载入(&L)...")));
                connect(pLoadFamilyAction, SIGNAL(triggered(bool)), this, SLOT(LoadFamily()));
            }

            QAction* m_collapseItemsAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"全部折叠(&F)...")));
            connect(m_collapseItemsAction, SIGNAL(triggered(bool)), this, SLOT(collapseAll()));

            QAction* pExpandItemsAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"全部展开(&E)...")));
            connect(pExpandItemsAction, SIGNAL(triggered(bool)), this, SLOT(expandAll()));
        }
    }
    else if (selectedItem.size() > 1)
    {
        // 多选
        int nodeType = 0;
        for (QList<QTreeWidgetItem*>::const_iterator iter = selectedItem.begin(); iter != selectedItem.end(); ++iter)
        {
            QVariant typeData = (*iter)->data(0, FAMILY_USER_DATA_ROLE);
            nodeType = nodeType | typeData.toInt();
        }
        if (nodeType == TWNT_FAMILY)
        {
            if (m_bShowFamilyManagementMenuItem)
            {
                QAction* pRemoveFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除(&D)")));
                connect(pRemoveFamilyAction, SIGNAL(triggered(bool)), this, SLOT(RemoveFamily()));
            }
        }
    }
}

void QFamilyTreeWidget::OnFamilyTreeItemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QFamilyTreeWidgetUtil::EditFamilyTypeParameter(item);
}
